package com.yanqu.road.server.manger;

import com.yanqu.road.entity.battle.IBattleObjectInfo;
import com.yanqu.road.entity.config.battle.BattleResult;
import com.yanqu.road.entity.config.battle.PatronsBattleDetail;

import java.math.BigInteger;
import java.util.List;

/**
 * @Description
 * @Author cwq
 * @Data 2022/2/14 10:33
 */
public class BattleMgr {

    /**
     * 战斗 战斗力一样算 防守方胜利
     */
    public static BattleResult battle(long defenderId, List<IBattleObjectInfo> defendObjectList, int defendBuffValue, long attackerId, List<IBattleObjectInfo> attackObjectList, int attackBuffValue) {
        BattleResult battleResult = new BattleResult();
        int defendIndex = 0;
        int attackIndex = 0;
        IBattleObjectInfo defendObject = null;
        IBattleObjectInfo attackObject = null;
        long defendTotalBlood = 0;
        long attackTotalBlood = 0;

        long defendRemainBlood = 0;
        long attackRemainBlood = 0;
        while (true) {
            PatronsBattleDetail patronsBattleDetail;
            if(defendObject == null && defendObjectList.size() - 1 >= defendIndex){
                defendObject = defendObjectList.get(defendIndex);
                defendTotalBlood = defendRemainBlood = calAttackValue(defendObject,defendBuffValue);
            }
            if(attackObject == null && attackObjectList.size() - 1 >= attackIndex){
                attackObject = attackObjectList.get(attackIndex);
                attackTotalBlood = attackRemainBlood = calAttackValue(attackObject,attackBuffValue);
            }
            if(attackObject == null){
                battleResult.setWinUserId(defenderId);
                break;
            }
            if(defendObject == null){
                battleResult.setWinUserId(attackerId);
                break;
            }
            patronsBattleDetail = patronsBattle(defendObject,defendRemainBlood,defendTotalBlood, attackObject,attackRemainBlood,attackTotalBlood);

            battleResult.getPatronsBattleDetailList().add(patronsBattleDetail);
            defendRemainBlood = patronsBattleDetail.getEnemyPatronsCurrentBlood().longValue();
            attackRemainBlood = patronsBattleDetail.getMyPatronsCurrentBlood().longValue();

            if (defendRemainBlood <= 0) {
                defendIndex++;
                defendObject = null;
            }
            if (attackRemainBlood <= 0) {
                attackIndex++;
                attackObject = null;
            }
        }
        // 指的是击杀防守方的数量吗
        battleResult.setKillPatronsCount(defendIndex);
//        battleResult.setEnemyPatronsList(enemyPatronsList);
//        battleResult.setMyPatronsIdList(patronsIdList);

        return battleResult;
    }

    private static PatronsBattleDetail patronsBattle(IBattleObjectInfo defender, long defendRemainBlood , long defendTotalBlood , IBattleObjectInfo attacker, long attackRemainBlood, long attackTotalBlood) {
        PatronsBattleDetail battleDetail = new PatronsBattleDetail();

        long oldAttackRemainBlood = attackRemainBlood;
        long oldDefendRemainBlood = defendRemainBlood;

        attackRemainBlood = oldAttackRemainBlood - oldDefendRemainBlood;
        defendRemainBlood = oldDefendRemainBlood - oldAttackRemainBlood;

        battleDetail.setEnemyPatronsId(defender.getObjectId());
        battleDetail.setEnemyPatronsCurrentBlood(BigInteger.valueOf(defendRemainBlood));
        battleDetail.setEnemyPatronsTotalBlood(BigInteger.valueOf(defendTotalBlood));

        battleDetail.setMyPatronsId(attacker.getObjectId());
        battleDetail.setMyPatronsCurrentBlood(BigInteger.valueOf(attackRemainBlood));
        battleDetail.setMyPatronsTotalBlood(BigInteger.valueOf(attackTotalBlood));

        return battleDetail;
    }

    /**
     * 计算派遣对象的战斗力
     *
     * @param objectInfo
     * @param buffValue  buff 加成 千分比
     * @return
     */
    private static long calAttackValue(IBattleObjectInfo objectInfo, int buffValue) {
        return (objectInfo.getValue() * (1000 + objectInfo.getPlus()) / 1000 * (1000 + buffValue) + 1000 - 1) / 1000;
    }

    /**
     * 战斗 战斗力一样算 防守方胜利 不是车轮战
     */
    public static BattleResult battleBy1v1(long defenderId, List<IBattleObjectInfo> defendObjectList, int defendBuffValue, long attackerId, List<IBattleObjectInfo> attackObjectList, int attackBuffValue) {
        BattleResult battleResult = new BattleResult();
        int attackWinNum = 0;
        int defendWinNum = 0;
        IBattleObjectInfo defendObject = null;
        IBattleObjectInfo attackObject = null;
        long defendTotalBlood = 0;
        long attackTotalBlood = 0;

        long defendRemainBlood = 0;
        long attackRemainBlood = 0;
        int maxObjectNum = Math.max(defendObjectList.size(), attackObjectList.size());
        for (int i = 0; i < maxObjectNum; i++) {
            if (defendObjectList.size() > i) {
                defendObject = defendObjectList.get(i);
            } else {
                defendObject = null;
            }

            if (attackObjectList.size() > i) {
                attackObject = attackObjectList.get(i);
            } else {
                attackObject = null;
            }

            if (attackObject == null) {
                battleResult.setDefendWinNum(battleResult.getDefendWinNum() + 1);
                continue;
            }
            if (defendObject == null) {
                battleResult.setAttackWinNum(battleResult.getAttackWinNum() + 1);
                continue;
            }

            PatronsBattleDetail patronsBattleDetail = patronsBattle(defendObject, defendRemainBlood, defendTotalBlood, attackObject, attackRemainBlood, attackTotalBlood);
            battleResult.getPatronsBattleDetailList().add(patronsBattleDetail);

            defendRemainBlood = patronsBattleDetail.getEnemyPatronsCurrentBlood().longValue();
            attackRemainBlood = patronsBattleDetail.getMyPatronsCurrentBlood().longValue();

            if (defendRemainBlood <= 0) {
                attackWinNum++;
            }
            if (attackRemainBlood <= 0) {
                defendWinNum++;
            }
        }
        if (attackWinNum > defendWinNum) {
            battleResult.setWinUserId(attackerId);
        }else{
            battleResult.setWinUserId(defenderId);
        }
        return battleResult;
    }

}
